package com.ridu.project.beshid.controller.api;

import com.ridu.project.beshid.api.GeneralResponse;
import com.ridu.project.beshid.entity.UserEntity;
import com.ridu.project.beshid.repository.UserRepository;
import com.ridu.project.beshid.service.UserService;
import com.ridu.project.beshid.utils.DateUtil;
import com.ridu.project.beshid.utils.SmsUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.UUID;

/**
 * Created by Administrator on 2017/6/22.
 */
@RestController
@Slf4j
public class LoginApiController {

    @Autowired
    private UserService userService;
    @Autowired
    private UserRepository userRepository;

    @PostMapping("/api/login")
    public GeneralResponse login(@RequestParam(required = false) String username, @RequestParam(required = false) String password, Model model){
        String error = null;
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            error = "用户名/密码错误";
            return GeneralResponse.error(error);
        } catch (IncorrectCredentialsException e) {
            error = "用户名/密码错误";
            return GeneralResponse.error(error);
        } catch (AuthenticationException e) {
            //其他错误，比如锁定，如果想单独处理请单独catch处理
            error = "其他错误：" + e.getMessage();
            log.error("其他错误",  e);
            return GeneralResponse.error(error);
        }
        UserEntity u = userService.findByUsername(username);
        u.setToken(UUID.randomUUID().toString().replace("-", ""));
        userRepository.saveAndFlush(u);
        GeneralResponse r = new GeneralResponse();
        r.setData(u.getToken());
        r.setMessage("成功");
        return r;
    }

    @PostMapping("/api/sms/login")
    public GeneralResponse smsLogin(@RequestParam(required = false) String username, @RequestParam(required = false) String code, Model model){
        UserEntity u = userRepository.findOneByUsernameAndCode(username, code);
        if(StringUtils.isNotBlank(username) && u != null && StringUtils.isNotBlank(u.getUsername())){
            u.setToken(UUID.randomUUID().toString().replace("-", ""));
            userRepository.saveAndFlush(u);
            GeneralResponse r = new GeneralResponse();
            r.setData(u.getToken());
            r.setMessage("成功");
            return r;
        } else {
            return GeneralResponse.error("验证失败");
        }

    }

    @PostMapping("/api/register")
    public GeneralResponse register(@RequestParam(required = false) String username, String password, Model model){
        UserEntity u = userRepository.findByUsername(username);
        if(StringUtils.isNotBlank(username) && u != null && StringUtils.isNotBlank(u.getUsername())){
            return GeneralResponse.error("用户已存在");
        } else {
            u = new UserEntity();
        }
        u.setUsername(username);
        String salt1 = new Date().toString();
        u.setPassword(new Sha256Hash(password, salt1).toBase64());
        u.setSalt(salt1);
        u.setToken(UUID.randomUUID().toString().replace("-", ""));
        u.setDateCreated(new Date());
        userRepository.save(u);
        GeneralResponse r = new GeneralResponse();
        r.setData(u.getToken());
        r.setMessage("注册成功");
        return r;

    }

    @PostMapping("/api/sms/send")
    public GeneralResponse smsSend(@RequestParam(required = false) String username, Model model){
        if(StringUtils.isBlank(username)){
            return GeneralResponse.error("用户名不能为空");
        }
        UserEntity u = userRepository.findByUsername(username);
        if(u != null && StringUtils.isNotBlank(u.getUsername())){

        } else {
            u = new UserEntity();
            u.setUsername(username);
            u.setDateCreated(new Date());
            userRepository.save(u);
        }
        if(u.getPassTime() != null && new Date().before(u.getPassTime())){
            return GeneralResponse.error("您已经发送，请重试");
        }
        int code = (int)(Math.random()*1000000);
        SmsUtil.send(code+"" ,username);
        u.setCode(code + "");
        u.setPassTime(DateUtil.addTime(new Date(), 5));
        userRepository.saveAndFlush(u);
        return GeneralResponse.success("已发送，5分钟有效");

    }

    @PostMapping("/api/reset")
    public GeneralResponse smsSend(@RequestParam(required = false) String username,
                                   @RequestParam(required = false) String code,
                                   @RequestParam(required = false) String password, Model model){
        UserEntity user = userRepository.findByUsername(username);
        if(StringUtils.isNotBlank(username) && user != null && user.getCode().equals(code)){
            String salt1 = new Date().toString();
            user.setPassword(new Sha256Hash(password, salt1).toBase64());
            user.setSalt(salt1);
            userRepository.saveAndFlush(user);
            return GeneralResponse.success("成功");
        } else {
            return GeneralResponse.error("验证失败");
        }

    }

    @PostMapping("/api/logout")
    public GeneralResponse logout(@RequestParam String token, Model model){
        UserEntity user = userRepository.findOneByToken(token);
        if(user != null && user.getId() != null){
            user.setToken("");
            userRepository.saveAndFlush(user);
            return GeneralResponse.success("成功");
        } else {
            return GeneralResponse.error("验证失败");
        }

    }


}
